package com.zpz.framework.zpzoauth.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Maps;
import com.zpz.framework.zpzoauth.common.encrypt.ZpzOauthSaltUtil;
import com.zpz.framework.zpzoauth.common.redis.ZpzOauthRedisService;
import com.zpz.framework.zpzoauth.common.result.ZpzOauthResultMsg;
import com.zpz.framework.zpzoauth.common.result.ZpzOauthResultStatus;
import com.zpz.framework.zpzoauth.common.utils.*;
import com.zpz.framework.zpzoauth.dao.*;
import com.zpz.framework.zpzoauth.pojo.pe.*;
import com.zpz.framework.zpzoauth.pojo.po.*;
import com.zpz.framework.zpzoauth.pojo.qo.*;
import com.zpz.framework.zpzoauth.pojo.vo.*;
import com.zpz.framework.zpzoauth.service.ZpzOauthFrameUserService;
import io.netty.util.internal.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangpanzhi
 * @time 2019-07-09
 * @description 未经本人允许请勿随便改动，尊重劳动
 */
@Service
public class ZpzOauthFrameUserServiceImpl implements ZpzOauthFrameUserService {
    private Logger log = LoggerFactory.getLogger(ZpzOauthFrameUserServiceImpl.class);

    //登录密码最大错误次数
    private final static  int UserPasswordMaxErrorCount=3;
    //账户锁定时间 默认30分钟即 1800秒
    private final static  int LockAccountSeconds=1800;

    public static String APPLICATION_NAME;
    @Value("${zpzOauth.redis.pre}")
    public void setApplicationName(String applicationName){
        APPLICATION_NAME=applicationName;
    }
    @Resource
    private ZpzOauthRequestUtil zpzOauthRequestUtil;
    @Resource
    private FrameUserDepartmentMapper frameUserDepartmentMapper;
    @Resource
    private ZpzOauthFrameUserMapper zpzOauthFrameUserMapper;
    @Resource
    private ZpzOauthFrameRoleMapper zpzOauthFrameRoleMapper;
    @Resource
    private ZpzOauthFrameUserPasswordMapper zpzOauthFrameUserPasswordMapper;
    @Resource
    private ZpzOauthFrameUserRoleMapper zpzOauthFrameUserRoleMapper;
    @Resource
    private ZpzOauthRedisService zpzOauthRedisService;
    @Resource
    private ZpzOauthDataFrameUserGroupMapper dataOauthFrameUserGroupMapper;
    @Resource
    private ZpzOauthDataGroupAccessMapper zpzOauthDataGroupAccessMapper;
    @Resource
    private ZpzOauthFrameUserService zpzOauthFrameUserService;

    @Override
    public ZpzOauthResultMsg<PageInfo<GetUserDepartmentVo>> getUserDepartment(GetUserDepartmentQo getUserDepartmentQo) {
        if (getUserDepartmentQo.getDepartmentId()==null){
            return ZpzOauthResultMsg.error("部门ID不能为空");
        }
        log.info("**********获取部门人员信息：：：参数：：：："+JSON.toJSONString(getUserDepartmentQo));
        PageHelper.startPage(getUserDepartmentQo).setOrderBy("fu.create_date desc");
        GetUserDepartmentInfoPe g=new GetUserDepartmentInfoPe();
        g.setId(getUserDepartmentQo.getDepartmentId());
        g.setName(getUserDepartmentQo.getName());
        log.info("**********获取部门人员信息：：：参数：：：："+JSON.toJSONString(g));
        if (StringUtils.isNotBlank(getUserDepartmentQo.getName())){
            getUserDepartmentQo.setName(getUserDepartmentQo.getName().replaceAll("%","％"));
            getUserDepartmentQo.setName(getUserDepartmentQo.getName().replaceAll("_","＿"));
            getUserDepartmentQo.setName(getUserDepartmentQo.getName().replaceAll("'","＇"));
        }
        List<GetUserDepartmentPe> list = zpzOauthFrameUserMapper.selectUserDepartment(g);
        PageInfo<GetUserDepartmentVo> page = new ZpzOauthPageInfoExt<GetUserDepartmentPe, GetUserDepartmentVo>().getPage(list, GetUserDepartmentVo.class);
        return ZpzOauthResultMsg.okForData(page);
    }
    /**
     * region 获取（端+用户）密码用户密码 getPwd
     * @name: getPwd
     * @createDate: 2021/2/22 11:05
     * @param clientId
     * @param ucode
     * @return: java.lang.String
     * @throws:
     */
    private String getPwd(String clientId, String ucode) {
        FrameUserPassword p = new FrameUserPassword();
        p.setClientId(clientId);
        p.setUserCode(ucode);
        p.setDeleteStatus(0);
        List<FrameUserPassword> pwd = zpzOauthFrameUserPasswordMapper.select(p);
        if (pwd != null && pwd.size() > 0) {
            FrameUserPassword pw = pwd.get(0);
            return pw.getPassword();
        }
        return null;
    }
    //endregion

    @Override
    public ZpzOauthResultMsg<Boolean> mobileExist(String phoneNumber, String clientId) {
        // 校验用户是否存在
        FrameUser up = new FrameUser();
        up.setPhoneNumber(phoneNumber);
        up.setDelFlag(0);
        List<FrameUser> ups = zpzOauthFrameUserMapper.select(up);
        if (ups != null && ups.size() > 0) {
            FrameUser u = ups.get(0);
            //用户状态，1：正常，0：禁用，-1锁定
            if (u.getStatus() != 1) {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_CODE_NOT_NULL_30037, true);
            }
            //检验是否有绑定关系
            String type = u.getType();
            if (StringUtils.isNotBlank(type)) {
                if (type.contains(clientId)) {
                    //存在用户信息并且包含绑定关系
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_MOBILE_EXIST_ERROR_30008, true);
                } else {
                    //存在用户信息但是不包含绑定关系 -》可以注册
                    return ZpzOauthResultMsg.okForData(false);
                }
            } else {
                //存在用户信息但是不包含绑定关系 -》可以注册
                return ZpzOauthResultMsg.okForData(false);
            }
        } else {
            //不存在用户信息   -》可以注册
            return ZpzOauthResultMsg.okForData(false);
        }
    }

    @Override
    public ZpzOauthResultMsg<Boolean> forgetPwd(String clientId, ForgetPwdQo forgetPwdQo) {
        FrameUser fu = new FrameUser();
        fu.setPhoneNumber(forgetPwdQo.getPhoneNumber());
        fu.setDelFlag(0);
        List<FrameUser> fus = zpzOauthFrameUserMapper.select(fu);
        if (fus != null && fus.size() > 0) {
            // 用手机号查找 用户编号
            String userCode = fus.get(0).getUserCode();
            Integer i = modifyPwd(clientId, userCode, forgetPwdQo.getPassword(), 1);
            if (i != null && i > 0) {
                return ZpzOauthResultMsg.okForData(true);
            } else {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_PWD_FAIL_30009, false);
            }
        } else {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_INFO_BY_USER_NAME_30001);
        }
    }

    @Override
    public ZpzOauthResultMsg<String> registerByUserName(RegisterByUserNameQo registerByUserNameQo, String clientId) {
        // 校验用户是否存在
        FrameUser up = new FrameUser();
        up.setUserName(registerByUserNameQo.getUserName());
        up.setDelFlag(0);
        List<FrameUser> users = zpzOauthFrameUserMapper.select(up);
        if (users != null && users.size() > 0) {
            FrameUser u = users.get(0);
            //用户状态，1：正常，0：禁用，-1锁定
            if (u.getStatus() != 1) {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_CODE_NOT_NULL_30037, null);
            }
            //检验是否有绑定关系
            String type = u.getType();
            if (type.contains(clientId)) {
                //存在用户信息并且包含绑定关系
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_MOBILE_EXIST_ERROR_30018, null);
            } else {
                //存在用户信息但是不包含绑定关系 -》可以注册,添加绑定关系添加密码
                if (type.endsWith(",")) {
                    type = type.substring(0, type.lastIndexOf(","));
                }
                type = String.format("%s,%s",type,clientId);
                FrameUser uu = new FrameUser();
                uu.setUserCode(u.getUserCode());
                uu.setType(type);
                Integer re = zpzOauthFrameUserMapper.updateUserInfo(uu);
                if (re != null && re > 0) {
                    // 修改登录密码
                    String password = registerByUserNameQo.getPassword();
                    modifyPwd(clientId, u.getUserCode(), password, 1);
                    //创建账户
                    return ZpzOauthResultMsg.okForData(u.getUserCode());
                } else {
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_NAME_NOT_NULL_30017, null);
                }
            }
        } else {
            //不存在用户信息   -》可以注册 添加用户信息绑定关系密码
            //不存在用户信息,注册即是添加用户关系并且添加绑定关系
            ZpzOauthSnowflakeIdWorker idWorker = new ZpzOauthSnowflakeIdWorker(10, 10);
            String ucode = String.valueOf(idWorker.nextId());
            FrameUser u = new FrameUser();
            u.setUserName(registerByUserNameQo.getUserName());
            u.setUniqueNumber(registerByUserNameQo.getUniqueNumber());
            u.setSourceClient(registerByUserNameQo.getSource());
            u.setDelFlag(0);
            u.setUserCode(ucode);
            u.setCreateBy(ucode);
            u.setCreateDate(new Date());
            u.setStatus(1);
            u.setDefaultFlag(0);
            u.setType(clientId);
            Integer i = zpzOauthFrameUserMapper.insert(u);
            if (i != null && i > 0) {
                // 修改登录密码
                String pwd = registerByUserNameQo.getPassword();
                modifyPwd(clientId, ucode, pwd, 1);
                return ZpzOauthResultMsg.okForData(ucode);
            }
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_NAME_NOT_NULL_30017);
        }
    }

    /**
     * 注册
     */
    @Override
    public ZpzOauthResultMsg<Boolean> register(RegisterQo registerQo, String clientId) {
        // 校验用户是否存在
        FrameUser up = new FrameUser();
        up.setPhoneNumber(registerQo.getPhoneNumber());
        up.setDelFlag(0);
        List<FrameUser> ups = zpzOauthFrameUserMapper.select(up);
        if (ups != null && ups.size() > 0) {
            FrameUser u = ups.get(0);
            //用户状态，1：正常，0：禁用，-1锁定
            if (u.getStatus() != 1) {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_CODE_NOT_NULL_30037, true);
            }
            //检验是否有绑定关系
            String type = u.getType();
            if (type.contains(clientId)) {
                //存在用户信息并且包含绑定关系
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_MOBILE_EXIST_ERROR_30008, true);
            } else {
                //存在用户信息但是不包含绑定关系 -》可以注册,添加绑定关系添加密码
                if (type.endsWith(",")) {
                    type = type.substring(0, type.lastIndexOf(","));
                }
                type = type + "," + clientId;
                FrameUser uu = new FrameUser();
                uu.setUserCode(u.getUserCode());
                uu.setType(type);
                Integer integer = zpzOauthFrameUserMapper.updateUserInfo(uu);
                if (integer != null && integer > 0) {
                    // 修改登录密码
                    String pwd = registerQo.getPassword();
                    modifyPwd(clientId, u.getUserCode(), pwd, 1);
                    //创建账户
                    return ZpzOauthResultMsg.okForData(true);
                } else {
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_NAME_NOT_NULL_30017, true);
                }
            }
        } else {
            //不存在用户信息   -》可以注册 添加用户信息绑定关系密码
            //不存在用户信息,注册即是添加用户关系并且添加绑定关系
            ZpzOauthSnowflakeIdWorker idWorker = new ZpzOauthSnowflakeIdWorker(10, 10);
            String ucode = String.valueOf(idWorker.nextId());
            FrameUser u = new FrameUser();
            u.setPhoneNumber(registerQo.getPhoneNumber());
            u.setUserName(registerQo.getUserName());
            u.setSourceClient(registerQo.getSource());
            u.setDelFlag(0);
            u.setUserCode(ucode);
            u.setCreateBy(ucode);
            u.setCreateDate(new Date());
            u.setStatus(1);
            u.setDefaultFlag(0);
            u.setType(clientId);
            Integer i = zpzOauthFrameUserMapper.insert(u);
            if (i != null && i > 0) {
                // 修改登录密码
                String pwd = registerQo.getPassword();
                modifyPwd(clientId, ucode, pwd, 1);
                return ZpzOauthResultMsg.okForData(true);
            }
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_NAME_NOT_NULL_30017);
        }
    }
    /**
     * 修改（端+用户）密码  [用该方法的时候注意密码传进来的时候为明文，否则会使密码加密两次，造成无法登录的现象]
     */
    @Override
    public Integer modifyPwd(String clientId, String ucode, String password, int defaultFlag) {
        FrameUserPassword p = new FrameUserPassword();
        p.setClientId(clientId);
        p.setUserCode(ucode);
        p.setDeleteStatus(0);
        List<FrameUserPassword> pds = zpzOauthFrameUserPasswordMapper.select(p);
        if (pds != null && pds.size() > 0) {
            FrameUserPassword pw = pds.get(0);
            FrameUserPassword obj = new FrameUserPassword();
            obj.setId(pw.getId());
            if (StringUtils.isNotBlank(password)) {
                String pwd = ZpzOauthSaltUtil.getPwd(password);
                obj.setPassword(pwd);
                obj.setDefaultFlag(defaultFlag);
                obj.setUpdateBy(ucode);
                obj.setUpdateDate(new Date());
            }
            Integer integer = zpzOauthFrameUserPasswordMapper.updateUserPwd(obj);
            return integer;
        } else {
            //插入端密码
            FrameUserPassword t = new FrameUserPassword();
            t.setDeleteStatus(0);
            t.setUserCode(ucode);
            t.setClientId(clientId);
            t.setDefaultFlag(defaultFlag);
            t.setCreateBy(ucode);
            t.setCreateDate(new Date());
            if (StringUtils.isNotBlank(password)) {
                String pwd = ZpzOauthSaltUtil.getPwd(password);
                t.setPassword(pwd);
            }
            int integer = zpzOauthFrameUserPasswordMapper.insert(t);
            return integer;
        }
    }
    //endregion

    @Override
    public ZpzOauthResultMsg<UserAuthenticationVo> getUserInfoByUserName(String username, String clientId) {
        FrameUser fu = new FrameUser();
        fu.setUserName(username);
        fu.setDelFlag(0);
        List<FrameUser> fus = zpzOauthFrameUserMapper.select(fu);
        if (fus != null && fus.size() > 0) {
            FrameUser fur = fus.get(0);
            UserAuthenticationVo uav = new UserAuthenticationVo();
            BeanUtils.copyProperties(fur, uav);
            String pd = getPwd(clientId, fur.getUserCode());
            if (StringUtils.isNotBlank(pd)) {
                uav.setPassword(pd);
            }
            return ZpzOauthResultMsg.okForData(uav);
        }
        return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.OAUTH_10000);
    }
    // 根据用户编号获取用户的部门，部门限制用户权限
    @Override
    public ZpzOauthResultMsg<Authorize> getAuthorizeDepartment(String userCode) {
        //获取用户角色
        List<String> roles = zpzOauthFrameRoleMapper.selectDepartmentByUesr( userCode);
        Authorize au = new Authorize();
        au.setRoles(roles);
        return ZpzOauthResultMsg.okForData(au);
    }

    @Override
    public ZpzOauthResultMsg<Authorize> getAuthorize(String userCode, String clientId) {
        //获取用户角色
        List<String> roles = zpzOauthFrameRoleMapper.selectRoleByClientAndUser(clientId, userCode);
        Authorize au = new Authorize();
        au.setRoles(roles);
        return ZpzOauthResultMsg.okForData(au);
    }

    @Override
    public ZpzOauthResultMsg<UserAuthenticationVo> findUserByPhoneNumberCodeLogin(String phoneNumber, String clientId
            ,String sourceClient) {
        FrameUser fu = new FrameUser();
        fu.setPhoneNumber(phoneNumber);
        fu.setDelFlag(0);
        List<FrameUser> fus = zpzOauthFrameUserMapper.select(fu);
        if (fus != null && fus.size() > 0) {
            FrameUser frameUser = fus.get(0);

            //检验是否有绑定关系
            String type = frameUser.getType();
            if (!type.contains(clientId)) {
                //存在用户信息但是不包含绑定关系 -》可以注册,添加绑定关系添加密码
                if (type.endsWith(",")) {
                    type = type.substring(0, type.lastIndexOf(","));
                }
                type = type + "," + clientId;
                FrameUser uu = new FrameUser();
                uu.setUserCode(frameUser.getUserCode());
                uu.setType(type);
                Integer integer = zpzOauthFrameUserMapper.updateUserInfo(uu);
                if (integer != null && integer > 0) {
                    // 修改登录密码
                    String pwd = ZpzOauthCommonConstant.DEFAULT_PASSWORD;
                    modifyPwd(clientId, frameUser.getUserCode(), pwd, 1);
                }
            }
            UserAuthenticationVo uav = new UserAuthenticationVo();
            BeanUtils.copyProperties(frameUser, uav);
            String pd = getPwd(clientId, frameUser.getUserCode());
            if (StringUtils.isNotBlank(pd)) {
                uav.setPassword(pd);
            }
            return ZpzOauthResultMsg.okForData(uav);
        } else {
            ZpzOauthSnowflakeIdWorker idWorker = new ZpzOauthSnowflakeIdWorker(10, 10);
            String ucode = String.valueOf(idWorker.nextId());
            FrameUser u = new FrameUser();
            u.setPhoneNumber(phoneNumber);
            u.setDelFlag(0);
            u.setUserCode(ucode);
            u.setCreateBy(ucode);
            u.setCreateDate(new Date());
            u.setStatus(1);
            u.setType(clientId);
            u.setSourceClient(sourceClient);
            Integer i = zpzOauthFrameUserMapper.insert(u);
            if (i != null && i > 0) {
                // 修改登录密码
                String pwd = ZpzOauthCommonConstant.DEFAULT_PASSWORD;
                Integer integer = modifyPwd(clientId, ucode, pwd, 1);
                UserAuthenticationVo uav = new UserAuthenticationVo();
                uav.setPhoneNumber(phoneNumber);
                uav.setUserCode(ucode);
                uav.setType(clientId);
                uav.setStatus(1);
                uav.setRegisterStatus(1);
                return ZpzOauthResultMsg.okForData(uav);
            }
        }
        return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.OAUTH_10001);
    }

    @Override
    public ZpzOauthResultMsg<UserAuthenticationVo> findUserByUsernameAndUniquenum(String key, String clientId) {
        FrameUser fu = new FrameUser();
        fu.setUserName(key);
        fu.setUniqueNumber(key);
        fu.setDelFlag(0);
        List<FrameUser> fus = zpzOauthFrameUserMapper.selectUserInfoByUserNameAndUniqueNum(fu);
        if (fus != null && fus.size() > 0) {
            FrameUser frameUser = fus.get(0);
            UserAuthenticationVo uav = new UserAuthenticationVo();
            BeanUtils.copyProperties(frameUser, uav);
            String pd = getPwd(clientId, frameUser.getUserCode());
            if (StringUtils.isNotBlank(pd)) {
                uav.setPassword(pd);
            }
            return ZpzOauthResultMsg.okForData(uav);
        }
        return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.OAUTH_10013);
    }

    @Override
    public ZpzOauthResultMsg<UserAuthenticationVo> findUserByPhoneNumber(String phoneNumber, String clientId) {
        FrameUser fu = new FrameUser();
        fu.setPhoneNumber(phoneNumber);
        fu.setDelFlag(0);
        List<FrameUser> fus = zpzOauthFrameUserMapper.select(fu);
        if (fus != null && fus.size() > 0) {
            FrameUser frameUser = fus.get(0);
            UserAuthenticationVo uav = new UserAuthenticationVo();
            BeanUtils.copyProperties(frameUser, uav);
            String pd = getPwd(clientId, frameUser.getUserCode());
            if (StringUtils.isNotBlank(pd)) {
                uav.setPassword(pd);
            }
            return ZpzOauthResultMsg.okForData(uav);
        }
        return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.OAUTH_10001);
    }

    @Override
    public ZpzOauthResultMsg<Boolean> validUserPasswordLocked(String ucode, String clientId) {
        FrameUserPassword frameUserPassword = new FrameUserPassword();
        frameUserPassword.setDeleteStatus(0);
        frameUserPassword.setUserCode(ucode);
        frameUserPassword.setClientId(clientId);
        List<FrameUserPassword> ts = zpzOauthFrameUserPasswordMapper.select(frameUserPassword);
        log.info(":::::::锁定账号：" + JSON.toJSONString(ts));
        if (ts != null && ts.size() > 0) {
            FrameUserPassword t = ts.get(0);
            String forgetPwdLock = t.getForgetPwdLock();
            if (StringUtils.isNotBlank(forgetPwdLock) && forgetPwdLock.equals("1")) {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.OAUTH_10014, false);
            }
            return ZpzOauthResultMsg.okForData(true);
        }
        return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.OAUTH_10002, false);
    }

    @Override
    public ZpzOauthResultMsg<Boolean> modifyUserLoginDate(ModifyUserLoginDateQo modifyUserLoginDateQo) {
        FrameUserPassword t = new FrameUserPassword();
        t.setUserCode(modifyUserLoginDateQo.getUserCode());
        t.setClientId(modifyUserLoginDateQo.getClientId());
        t.setLoginDate(modifyUserLoginDateQo.getLoginDate());
        t.setUpdateBy(modifyUserLoginDateQo.getUserCode());
        t.setUpdateDate(new Date());
        Integer integer = zpzOauthFrameUserPasswordMapper.updateUserLoginDate(t);
        if (integer != null && integer > 0) {
            return ZpzOauthResultMsg.okForData(true);
        }
        return ZpzOauthResultMsg.okForData(false);
    }

    @Override
    public ZpzOauthResultMsg<GetUserInfoVo> getUserInfo(String clientId,String userCode) {
        FrameUser u = new FrameUser();
        u.setUserCode(userCode);
        u.setDelFlag(0);
        u.setStatus(1);
        FrameUser frameUser = zpzOauthFrameUserMapper.selectOne(u);
        if (frameUser != null) {
            GetUserInfoVo getUserInfoVo = new GetUserInfoVo();
            BeanUtils.copyProperties(frameUser, getUserInfoVo);
            FrameUserPassword up=new FrameUserPassword();
            up.setClientId(clientId);
            up.setUserCode(userCode);
            up.setDeleteStatus(0);
            List<FrameUserPassword> ups = zpzOauthFrameUserPasswordMapper.select(up);
            if (ups!=null&&ups.size()>0&&ups.get(0).getLoginDate()!=null){
                getUserInfoVo.setLoginDate(DateUtils.formatDate(ups.get(0).getLoginDate(),"yyyy-MM-dd HH:mm:ss"));
            }
            String idCardNumber = getUserInfoVo.getIdCardNumber();
            if (StringUtils.isNotBlank(idCardNumber)) {
                if (idCardNumber.length() == 15) {
                    idCardNumber = idCardNumber.substring(0, 4) + "*********" + idCardNumber.substring(13);
                } else if (idCardNumber.length() == 18) {
                    idCardNumber = idCardNumber.substring(0, 4) + "************" + idCardNumber.substring(16);
                }
                getUserInfoVo.setEncryIdCardNumber(idCardNumber);
            }
            FrameUserDataGroup frameUserDataGroup=new FrameUserDataGroup();
            frameUserDataGroup.setDelFlag(0);
            frameUserDataGroup.setUserCode(userCode);
            List<FrameUserDataGroup> frameUserDataGroupList = dataOauthFrameUserGroupMapper.select(frameUserDataGroup);
            if (frameUserDataGroupList!=null && frameUserDataGroupList.size()>0){
                List<String> groupCodeList=frameUserDataGroupList.stream().map(FrameUserDataGroup::getGroupCode).collect(Collectors.toList());
                Map mapParam = new HashMap();
                mapParam.put("groupCodes",groupCodeList);
                List<DataGroupAccessPe> dataGroupAccessPeList = zpzOauthDataGroupAccessMapper.selectDateGroupAccessListByGroupCodes(mapParam);
                if(dataGroupAccessPeList!=null && dataGroupAccessPeList.size()>0){
                    List<String> dataAccess=dataGroupAccessPeList.stream().map(DataGroupAccessPe::getDataAccessVal).collect(Collectors.toList());
                    getUserInfoVo.setDataAccess(dataAccess);
                }
            }

            return ZpzOauthResultMsg.okForData(getUserInfoVo);
        }
        return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_NAME_NOT_NULL_30025, null);
    }
    //endregion

    //region 添加成员 addMember
    /**
     * 添加成员
     */
    @Override
    public ZpzOauthResultMsg<String> addMember(HttpServletRequest request, InsertMemberQo insertMemberQo) {
        Map<String, String> license = ZpzOauthRequestUtil.getLicense(request);
        if (license==null || license.size()==0){
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10023);
        }
        String ucodeLicense = license.get("ucode");
        if (StringUtils.isBlank(ucodeLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10027);
        }
        try {
            //首先判断手机号是否注册
            GetFrameUserInfoPe getFrameUserInfoPe=new GetFrameUserInfoPe();
            getFrameUserInfoPe.setPhoneNumber(insertMemberQo.getPhoneNumber());
            getFrameUserInfoPe.setUserName(insertMemberQo.getUserName());
            FrameUser model = zpzOauthFrameUserMapper.selectFrameUser(getFrameUserInfoPe);

            if (model != null) {
                if (StringUtils.isBlank(model.getUserCode())) {
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_ID_NOT_AVAILABLE_30033);
                }
                if (model.getStatus() != 1) {
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_CODE_NOT_NULL_30037, "");
                }
                //检验是否有绑定关系
                String type = model.getType();
                if (StringUtils.isNotBlank(type) && type.contains((insertMemberQo.getClientId()))) {
                    //存在用户信息并且包含绑定关系
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_MOBILE_EXIST_ERROR_30008, "");
                }
                //存在用户信息但是不包含绑定关系 -》可以注册,添加绑定关系添加密码
                if (StringUtils.isNotBlank(type) && type.endsWith(",")) {
                    type = type.substring(0, type.lastIndexOf(","));
                }
                type = type + "," + insertMemberQo.getClientId();
                FrameUser uu = new FrameUser();
                uu.setUserCode(model.getUserCode());
                uu.setType(type);
                uu.setName(insertMemberQo.getMemberName());
                uu.setUserName(insertMemberQo.getUserName());
                uu.setPhoneNumber(insertMemberQo.getPhoneNumber());
                uu.setAddress(insertMemberQo.getAddress());
                uu.setRemarks(insertMemberQo.getRemarks());
                uu.setUpdateDate(new Date());
                uu.setUpdateBy(ucodeLicense);
                Integer integer = zpzOauthFrameUserMapper.updateUserInfo(uu);
                if (integer != null && integer > 0) {
                    // 添加登录密码
                    Integer i = modifyMemberPwd(insertMemberQo.getClientId(), model.getUserCode(), insertMemberQo.getPassword(),ucodeLicense);
                    //添加用户角色
                    OauthClientDetails client = zpzOauthRequestUtil.getClient(insertMemberQo.getClientId());
                    if (client.getAccessType()==0||client.getAccessType()==1){
                        insertUserRole(insertMemberQo.getUserRoleCode(), model.getUserCode(), insertMemberQo.getClientId(),ucodeLicense);
                    } else if (client.getAccessType()==2){
                        insertUserDepartment(insertMemberQo.getUserRoleCode(), model.getUserCode(), insertMemberQo.getClientId(),ucodeLicense);
                    }
                    return ZpzOauthResultMsg.okForData(model.getUserCode());
                } else {
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_NAME_NOT_NULL_30017, "");
                }
            } else {
                String ucode = ZpzOauthStringUtil.generatID();
                FrameUser u = new FrameUser();
                u.setPhoneNumber(insertMemberQo.getPhoneNumber());
                u.setUserName(insertMemberQo.getUserName());
                u.setDelFlag(0);
                u.setUserCode(ucode);
                u.setCreateBy(ucodeLicense);
                u.setCreateDate(new Date());
                u.setRemarks(insertMemberQo.getRemarks());
                u.setStatus(1);
                u.setType(insertMemberQo.getClientId());
                u.setDefaultFlag(0);
                u.setAddress(insertMemberQo.getAddress());
                u.setName(insertMemberQo.getMemberName());
                Integer i = zpzOauthFrameUserMapper.insert(u);
                if (i != null && i > 0) {
                    // 添加登录密码
                    modifyMemberPwd(insertMemberQo.getClientId(), ucode, insertMemberQo.getPassword(),ucodeLicense);
//                    insertUserRole(insertMemberQo.getUserRoleCode(), ucode, insertMemberQo.getClientId(),ucodeLicense);
                    //添加用户角色
                    OauthClientDetails client = zpzOauthRequestUtil.getClient(insertMemberQo.getClientId());
                    if (client.getAccessType()==0||client.getAccessType()==1){
                        insertUserRole(insertMemberQo.getUserRoleCode(), ucode, insertMemberQo.getClientId(),ucodeLicense);
                    } else if (client.getAccessType()==2){
                        insertUserDepartment(insertMemberQo.getUserRoleCode(), ucode, insertMemberQo.getClientId(),ucodeLicense);
                    }
                }
                return ZpzOauthResultMsg.okForData(ucode);
            }
        } catch (Exception e) {
            log.info("手机号是" + insertMemberQo.getPhoneNumber() + ",添加成员的时候异常：e=" + e.getMessage());
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.ADD_USER_ERROR_30029);
        }

    }

    /**
     * 修改（端+用户）密码[只供添加成员信息的密码修改]
     */
    private Integer modifyMemberPwd(String clientId, String ucode, String password,String ucodeLicense) {
        FrameUserPassword p = new FrameUserPassword();
        p.setClientId(clientId);
        p.setUserCode(ucode);
        p.setDeleteStatus(0);
        List<FrameUserPassword> pds = zpzOauthFrameUserPasswordMapper.select(p);
        if (pds != null && pds.size() > 0) {
            FrameUserPassword pw = pds.get(0);
            FrameUserPassword obj = new FrameUserPassword();
            obj.setId(pw.getId());
            if (StringUtils.isNotBlank(password)) {
//                String pwd = ZpzOauthMd5SaltUtil.getPwd(password).toLowerCase();
                String pwd = ZpzOauthSaltUtil.getPwd(password);
                obj.setPassword(pwd);
                obj.setDefaultFlag(0);
                obj.setUpdateBy(ucodeLicense);
                obj.setUpdateDate(new Date());
                obj.setCreateDate(new Date());
            }
            Integer integer = zpzOauthFrameUserPasswordMapper.updateMemberPwd(obj);
            return integer;
        } else {
            //插入端密码
            FrameUserPassword t = new FrameUserPassword();
            t.setDeleteStatus(0);
            t.setUserCode(ucode);
            t.setClientId(clientId);
            t.setDefaultFlag(0);
            t.setCreateBy(ucodeLicense);
            t.setCreateDate(new Date());
            if (StringUtils.isNotBlank(password)) {
//                String pwd = ZpzOauthMd5SaltUtil.getPwd(password).toLowerCase();
                String pwd = ZpzOauthSaltUtil.getPwd(password);
                t.setPassword(pwd);
            }
            int integer = zpzOauthFrameUserPasswordMapper.insert(t);
            return integer;
        }
    }

    /**
     * 添加用户角色
     */
    private ZpzOauthResultMsg<Boolean> insertUserRole(String userRoleCode, String uCode, String clientId,String ucodeLicense) {
        try {
            FrameUserRole ur = new FrameUserRole();
            ur.setUserCode(uCode);
            ur.setRoleCode(userRoleCode);
            ur.setCreateBy(ucodeLicense);
            ur.setClientId(clientId);
            ur.setCreateDate(new Date());
            ur.setDelFlag(0);
            Integer i = zpzOauthFrameUserRoleMapper.insert(ur);
            if (i > 0) {
                return ZpzOauthResultMsg.ok();
            } else {
                return ZpzOauthResultMsg.error("添加用户角色失败");
            }
        } catch (Exception e) {
            log.info("添加用户角色失败,uCode是" + uCode + "，异常信息是=" + e.toString());
            return ZpzOauthResultMsg.error("添加用户角色异常");
        }
    }
    /**
     * 添加用户角色
     */
    private ZpzOauthResultMsg<Boolean> insertUserDepartment(String userRoleCode, String uCode, String clientId,String ucodeLicense) {
        try {
            FrameUserDepartment ur = new FrameUserDepartment();
            ur.setUserCode(uCode);
            ur.setDepartmentId(Long.parseLong(userRoleCode));
            ur.setCreateBy(ucodeLicense);
//            ur.setClientId(clientId);
            ur.setCreateDate(new Date());
            ur.setDelFlag(0);
            Integer i = frameUserDepartmentMapper.insert(ur);
            if (i > 0) {
                return ZpzOauthResultMsg.ok();
            } else {
                return ZpzOauthResultMsg.error("添加用户部门关系失败");
            }
        } catch (Exception e) {
            log.info("添加用户角色失败,uCode是" + uCode + "，异常信息是=" + e.toString());
            return ZpzOauthResultMsg.error("添加用户部门关系异常");
        }
    }
    //endregion

    //region 删除成员
    /**
     * 删除成员
     */
    @Override
    public ZpzOauthResultMsg<Boolean> deleteMember(String uCode, String clientId) {
        try {
            ZpzOauthResultMsg<FrameUser> result = selectFrameUser(uCode, clientId);
            if (result.getData() == null) {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_ID_NOT_AVAILABLE_30033);
            }
            //删除成员
            String type = result.getData().getType();
            Integer iFlag = type.indexOf(clientId);
            type = type.replace(clientId, "");
            if (type.endsWith(",")) {
                type = type.substring(0, type.lastIndexOf(","));
            }
            if (type.startsWith(",")) {
                type = type.substring(1, type.length());
            }
            FrameUser uu = new FrameUser();
            uu.setUserCode(uCode);
            uu.setType(type);
            Integer integer = zpzOauthFrameUserMapper.updateUserInfo(uu);
            if (integer > 0) {
                OauthClientDetails client = zpzOauthRequestUtil.getClient(clientId);
                if (client.getAccessType()==0||client.getAccessType()==1){
                    FrameUserRole frameUserRole = new FrameUserRole();
                    frameUserRole.setUserCode(uCode);
                    frameUserRole.setClientId(clientId);
                    frameUserRole.setDelFlag(1);
                    zpzOauthFrameUserRoleMapper.updateDelFlagById(frameUserRole);
                } else if (client.getAccessType()==2){
                    FrameUserDepartment frameUserRole = new FrameUserDepartment();
                    frameUserRole.setUserCode(uCode);
                    frameUserRole.setDelFlag(1);
                    frameUserDepartmentMapper.updateDelFlagById(frameUserRole);
                }
            }
            return ZpzOauthResultMsg.okForData(true);
        } catch (Exception e) {
            log.info("UserCode为" + uCode + ",删除成员的时候异常：e=" + e.toString());
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.DEL_USER_ERROR_30034);
        }
    }
    //endregion

    /**
     * 私有方法——更具用户Id（userId）获取用户信息
     */
    private ZpzOauthResultMsg<FrameUser> selectFrameUser(String userCode, String clientId) {
        GetFrameUserInfoPe getFrameUserInfoPe=new GetFrameUserInfoPe();
        getFrameUserInfoPe.setUserCode(userCode);
        FrameUser model = zpzOauthFrameUserMapper.selectFrameUser(getFrameUserInfoPe);
        if (model == null) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_ID_NOT_AVAILABLE_30033, null);
        }
        if (model.getStatus() != 1) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_CODE_NOT_NULL_30037, null);
        }
        //检验是否有绑定关系
        String type = model.getType();
        if (!type.contains(clientId)) {
            //存在用户信息并且包含绑定关系
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_ID_NOT_AVAILABLE_30033, null);
        }
        return ZpzOauthResultMsg.okForData(model);
    }

    /**
     * 查询成员详情
     */
    @Override
    public ZpzOauthResultMsg<SelectMemberDetailsVo> selectMemberDetails(SelectMemberDetailsQo selectMemberDetailsQo, String clientId) {
        SelectMemberDetailsVo vo = new SelectMemberDetailsVo();
        MemberRolePe pe = new MemberRolePe();
        BeanUtils.copyProperties(selectMemberDetailsQo, pe);
        pe.setType(clientId);
        MemberRolePe model = zpzOauthFrameRoleMapper.findMemberRolePe(pe);
        if (model != null) {
            BeanUtils.copyProperties(model, vo);
            return ZpzOauthResultMsg.okForData(vo);
        } else {
            return ZpzOauthResultMsg.okForData(null);
        }
    }

    /**
     * 分页查询成员详情
     */
    @Override
    public ZpzOauthResultMsg<PageInfo<SelectMemberDetailsVo>> pageSelectMemberDetails(PageSelectMemberDetailsQo pageSelectMemberDetailsQo) throws Exception {
        PageHelper.startPage(pageSelectMemberDetailsQo.getPageNum(), pageSelectMemberDetailsQo.getPageSize());
        MemberRolePe pe = new MemberRolePe();
        BeanUtils.copyProperties(pageSelectMemberDetailsQo, pe);
        List<MemberRolePe> memberRolePeList = zpzOauthFrameUserMapper.selectAllMemberRolePe(pe);
        PageInfo<MemberRolePe> pageList = new PageInfo<MemberRolePe>(memberRolePeList);
        PageInfo<SelectMemberDetailsVo> result = ZpzOauthBeanUtils.copyPageInfoProperties(pageList, SelectMemberDetailsVo.class);
        return ZpzOauthResultMsg.okForData(result);
    }

    /**
     * 修改成员信息
     */
    @Override
    public ZpzOauthResultMsg<Boolean> updateMemberInfo(HttpServletRequest request,UpdateMemberInfoQo updateMemberInfoQo) {
        Map<String, String> license = ZpzOauthRequestUtil.getLicense(request);
        if (license==null || license.size()==0){
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10023);
        }
        String ucodeLicense = license.get("ucode");
        if (StringUtils.isBlank(ucodeLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10027);
        }
        try {
            GetFrameUserInfoPe getFrameUserInfoPe=new GetFrameUserInfoPe();
            getFrameUserInfoPe.setUserCode(updateMemberInfoQo.getUserCode());
            getFrameUserInfoPe.setType(updateMemberInfoQo.getClientId());
            FrameUser model = zpzOauthFrameUserMapper.selectFrameUser(getFrameUserInfoPe);
            if (model == null) {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_ID_NOT_AVAILABLE_30033);
            }
            FrameUser fu = new FrameUser();
            fu.setRemarks(updateMemberInfoQo.getRemarks());
            fu.setUserCode(updateMemberInfoQo.getUserCode());
            fu.setName(updateMemberInfoQo.getName());
            fu.setUpdateDate(new Date());
            fu.setUpdateBy(ucodeLicense);
            FrameUserRole frameUserRole = new FrameUserRole();
            frameUserRole.setRoleCode(updateMemberInfoQo.getRoleCode());
            frameUserRole.setUserCode(updateMemberInfoQo.getUserCode());
            frameUserRole.setClientId(updateMemberInfoQo.getClientId());
            zpzOauthFrameUserMapper.updateFrameUser(fu);
            if (StringUtils.isNotBlank(updateMemberInfoQo.getPassword())) {
                Integer i = modifyPwd(updateMemberInfoQo.getClientId(), model.getUserCode(), updateMemberInfoQo.getPassword(), 1);
            }
            if (StringUtils.isNotBlank(updateMemberInfoQo.getRoleCode())) {
                String clientId = updateMemberInfoQo.getClientId();
                zpzOauthFrameUserRoleMapper.updateRoleCodeById(frameUserRole);
                OauthClientDetails client=zpzOauthRequestUtil.getClient(clientId);
                Integer accessType=client.getAccessType();
                String client_access_key=null;
                String ucode=updateMemberInfoQo.getUserCode();
                if (accessType== ZpzOauthCommonConstant.CLIENT_ACCESS_TYPE_1){
                    // 客户端控制权限
                    client_access_key=APPLICATION_NAME+"_"+"client_access:"+accessType+":"+clientId;
                }else if (accessType== 0){
                    // 角色控制权限
                    client_access_key=APPLICATION_NAME+"_"+"client_access:"+accessType+":"+clientId+":"+ucode;
                }else if (accessType== 2){
                    // 部门控制权限
                    client_access_key=APPLICATION_NAME+"_"+"client_access:"+accessType+":"+clientId+":"+ucode;
                }
                zpzOauthRedisService.delete(client_access_key);
            }

            changeUserFrameDataAccess(updateMemberInfoQo.getUserCode(),updateMemberInfoQo.getDataGroupCode(),updateMemberInfoQo.getRemarks(),updateMemberInfoQo.getUserCode());

            return ZpzOauthResultMsg.okForData(true);
        } catch (Exception e) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.UPDATE_USER_ERROR_30035);
        }
    }

    @Override
    public ZpzOauthResultMsg editStatus(String userCode, Integer status) throws Exception {
        int i = zpzOauthFrameUserMapper.updateStatus(userCode, status);
        if (i>0){
            return ZpzOauthResultMsg.okForData(true);
        }
        return ZpzOauthResultMsg.error("失败");
    }

    @Override
    public ZpzOauthResultMsg editStatus(EditStatusQo editStatusQo) throws Exception {
        // 校验用户是否存在
        FrameUser frameUser = new FrameUser();
        frameUser.setUserCode(editStatusQo.getUserCode());
        frameUser.setDelFlag(0);
        frameUser.setType(editStatusQo.getClientId());
        SelectUserInfoPe userInfoPe = zpzOauthFrameUserMapper.selectFrameUserby(frameUser);
        if (userInfoPe != null) {
            //用户状态，1：正常，0：禁用，-1锁定
            if (userInfoPe.getStatus() != 1) {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.MEMBER_CODE_NOT_NULL_30037, false);
            }
            //检验是否有绑定关系
            String lockType = userInfoPe.getLockType();
            // 包含该clientid表示已禁用状态
            if (StringUtils.isNotEmpty(lockType) && lockType.contains(editStatusQo.getClientId())) {
                // 并且要修改为禁用
                if (editStatusQo.getStatus().compareTo(0) == 0) {
                    // 直接返回成功
                    return ZpzOauthResultMsg.ok();
                }
                // 并且要修改为启用
                else if (editStatusQo.getStatus().compareTo(1) == 0) {
                    //  移除该clientid
                    if (lockType.contains(editStatusQo.getClientId() + ",")) {
                        lockType = lockType.replace(editStatusQo.getClientId() + ",", "");
                    } else if (lockType.endsWith(editStatusQo.getClientId())) {
                        lockType = lockType.replace(editStatusQo.getClientId(), "");
                    }
                    if (lockType.endsWith(",")) {
                        lockType = lockType.substring(0, lockType.lastIndexOf(","));
                    }
                    zpzOauthFrameUserMapper.updateStatusBy(editStatusQo.getUserCode(), lockType);
                    return ZpzOauthResultMsg.ok();
                } else {

                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.STATUS_IS_ERROR_30049);
                }
            }
            // 未包含该clientid表示已启用状态
            else {
                // 修改为禁用状态
                if (editStatusQo.getStatus().compareTo(0) == 0) {
                    // 添加该clientid
                    if (StringUtils.isEmpty(lockType)) {
                        lockType = editStatusQo.getClientId();
                    } else {
                        lockType = lockType + "," + editStatusQo.getClientId();
                    }
                    zpzOauthFrameUserMapper.updateStatusBy(editStatusQo.getUserCode(), lockType);
                    return ZpzOauthResultMsg.ok();
                }
                // 修改为启用状态
                else if (editStatusQo.getStatus().compareTo(1) == 0) {
                    // 直接返回成功
                    return ZpzOauthResultMsg.ok();
                } else {
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.STATUS_IS_ERROR_30049);
                }
            }

        } else {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_NOT_CLIENT_800017, false);
        }
    }

    @Override
    public ZpzOauthResultMsg<ModifyPasswordValidVo> modifyPasswordValid(ModifyPasswordValidQo modifyPasswordValidQo) {
        ModifyPasswordValidVo ret = new ModifyPasswordValidVo();
        //验证验证码是否正确
        ValidationSmsQo validationSmsQo = new ValidationSmsQo();
        validationSmsQo.setPhone(modifyPasswordValidQo.getPhoneNumber());
        validationSmsQo.setValidateContent(modifyPasswordValidQo.getShortMsgCode());

        //验证验证码是否正确
        boolean b = ZpzOauthMsgUtils.validateMsgCode(validationSmsQo.getPhone(), validationSmsQo.getValidateContent());
        if (!b) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_VALID_CODE_ERROR_30005);
        }

        ret.setValidCode(ZpzOauthStringUtil.generateNonceStr(16));
        ret.setValidStatus(0);
        //存入redis
        zpzOauthRedisService.set("ModifyPasswordValid-" + modifyPasswordValidQo.getPhoneNumber() + "-" + ret.getValidCode(), JSON.toJSONString(modifyPasswordValidQo), 900);
        return ZpzOauthResultMsg.okForData(ret);
    }

    /**
     * 功能描述: 修改密码
     *
     * @param modifyPasswordQo
     * @return
     * @author: lin
     * @date: 2019/5/31 15:39
     */
    @Override
    public ZpzOauthResultMsg<Boolean> modifyPassword(String clientId, ModifyPasswordQo modifyPasswordQo) {
        //新用户无需验证码验证
        if (modifyPasswordQo.getIsNewUser()==null || !modifyPasswordQo.getIsNewUser().equals(1)){
            // 1、验证 验证码 redis
            String retValidCode = zpzOauthRedisService.get("ModifyPasswordValid-" + modifyPasswordQo.getPhoneNumber() + "-" + modifyPasswordQo.getValidCode());
            if (StringUtil.isNullOrEmpty(retValidCode)) {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_PASSWORD_VALIDCOD_CHECK_EXPIRE_30041, false);
            }
        }
        ForgetPwdQo forgetPwdQo = new ForgetPwdQo();
        forgetPwdQo.setPassword(modifyPasswordQo.getPassword());
        forgetPwdQo.setPhoneNumber(modifyPasswordQo.getPhoneNumber());
        return forgetPwd(clientId, forgetPwdQo);
    }

    /**
     * 功能描述: 修改密码 （验证旧密码）
     *
     * @param modifyPasswordByPwQo
     * @author: zhangpanzhi
     * @date: 2019/7/19 15:39
     */
    @Override
    public ZpzOauthResultMsg<Boolean> modifyPasswordByOldPw(HttpServletRequest request, ModifyPasswordByPwQo modifyPasswordByPwQo) {
        Map<String, String> license = ZpzOauthRequestUtil.getLicense(request);
        if (license==null || license.size()==0){
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10023);
        }
        String clientIdLicense = license.get("clientId");
        if (StringUtils.isBlank(clientIdLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10026);
        }
        String ucodeLicense=license.get("ucode");
        if (StringUtils.isBlank(ucodeLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10027);
        }

        FrameUserPassword fup = new FrameUserPassword();
        fup.setUserCode(ucodeLicense);
        fup.setClientId(clientIdLicense);
        List<FrameUserPassword> fus = zpzOauthFrameUserPasswordMapper.select(fup);
        if (fus != null && fus.size() > 0) {
            FrameUserPassword objFup=fus.get(0);
            String oldpwd = ZpzOauthMd5SaltUtil.getPwd(modifyPasswordByPwQo.getOldPassword());

            if (objFup.getPassword().equalsIgnoreCase(oldpwd)){
                Integer i = modifyPwd(clientIdLicense, ucodeLicense, modifyPasswordByPwQo.getPassword(), 1);
                if (i != null && i > 0) {
                    return ZpzOauthResultMsg.okForData(true);
                } else {
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_PWD_FAIL_30009, false);
                }
            }else {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_PASSWORD_OLDPWD_FAILURE_31005, false);
            }
        } else {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_INFO_BY_USER_NAME_30001);
        }
    }

    /**
     *
     * 功能描述: 首次登录修改密码
     *
     * @param modifyPasswordByFirstLoginQo
     * @return
     * @author: zhangpanzhi
     * @date: 2020/4/7 15:39
     */
    @Override
    public ZpzOauthResultMsg<Boolean> modifyPasswordByFirstLogin(Map<String, String> license,ModifyPasswordByFirstLoginQo modifyPasswordByFirstLoginQo){
        String clientIdLicense = license.get("clientId");
        if (StringUtils.isBlank(clientIdLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10026);
        }
        String ucodeLicense=license.get("ucode");
        if (StringUtils.isBlank(ucodeLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10027);
        }

        FrameUserPassword fup = new FrameUserPassword();
        fup.setUserCode(ucodeLicense);
        fup.setClientId(clientIdLicense);
        List<FrameUserPassword> fus = zpzOauthFrameUserPasswordMapper.select(fup);
        if (fus != null && fus.size() > 0) {
            FrameUserPassword frameUserPassword=fus.get(0);
            if (frameUserPassword.getDefaultFlag().equals(1)){
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_ISFIRST_LOGIN_31055);
            }
            // 校验旧密码
            if (StringUtils.isNotBlank(modifyPasswordByFirstLoginQo.getOldPassword())){
                String oldpwd = ZpzOauthMd5SaltUtil.getPwd(modifyPasswordByFirstLoginQo.getOldPassword());
                if (!frameUserPassword.getPassword().equalsIgnoreCase(oldpwd)){
                    return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_PASSWORD_OLDPWD_FAILURE_31005, false);
                }
            }
            Integer i = modifyPwd(clientIdLicense, ucodeLicense, modifyPasswordByFirstLoginQo.getPassword(), 1);
            if (i != null && i > 0) {
                return ZpzOauthResultMsg.okForData(true);
            } else {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_PWD_FAIL_30009);
            }
        } else {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_INFO_BY_USER_NAME_30001);
        }
    }

    /**
     *
     * 功能描述: 验证密码错误登录
     *
     * @param validUserPasswordQo
     * @return
     * @author: zhangpanzhi
     * @date: 2019/5/31 15:39
     */
    @Override
    public ZpzOauthResultMsg<ValidUserPasswordVo> validUserPassword(ValidUserPasswordQo validUserPasswordQo) throws Exception{

        int errorCount=0;
        ValidUserPasswordVo ret=new ValidUserPasswordVo();

        //根据手机号码获取用户信息
        FrameUser fu = new FrameUser();
        fu.setPhoneNumber(validUserPasswordQo.getPhoneNumber());
        fu.setDelFlag(0);
        List<FrameUser> fus = zpzOauthFrameUserMapper.select(fu);
        String userCode="";
        if (fus!=null&&fus.size()>0){
            userCode=fus.get(0).getUserCode();
        }else{
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_INFO_BY_USER_NAME_30001);
        }

        //根据用户编号和客户端id获取密码信息
        FrameUserPassword selectFrameUserPassword=new FrameUserPassword();
        selectFrameUserPassword.setDeleteStatus(0);
        selectFrameUserPassword.setClientId(validUserPasswordQo.getClientId());
        selectFrameUserPassword.setUserCode(userCode);
        List<FrameUserPassword> frameUserPasswordList=zpzOauthFrameUserPasswordMapper.select(selectFrameUserPassword);

        if (frameUserPasswordList!=null && frameUserPasswordList.size()>0){
            FrameUserPassword frameUserPassword=frameUserPasswordList.get(0);

            //算取锁定时间
            long lockMinute=0;
            if (frameUserPassword.getForgetPwdLockTime()!=null){
                Calendar dateCur=Calendar.getInstance();
                Calendar dateLockTime=Calendar.getInstance();
                dateCur.setTime(new Date());
                dateLockTime.setTime(frameUserPassword.getForgetPwdLockTime());
                long timeCur=dateCur.getTimeInMillis();
                long timeLockTime=dateLockTime.getTimeInMillis();
                //转化minute
                lockMinute=(timeCur-timeLockTime)/(1000*60);
            }

            if((StringUtils.isNotBlank(frameUserPassword.getForgetPwdLock()) && frameUserPassword.getForgetPwdLock().equals("1")) && lockMinute<30){
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_ERROR_30048);
            }

            String redisKey=APPLICATION_NAME+"-validUserPwdErrorCount-"+validUserPasswordQo.getClientId()+"-"+frameUserPassword.getUserCode();

            //获取当前缓存错误次数
            String errorCountStr = zpzOauthRedisService.get(redisKey);
            if (!StringUtil.isNullOrEmpty(errorCountStr)){
                errorCount=Integer.parseInt(errorCountStr);
            }

            String pwd = ZpzOauthMd5SaltUtil.getPwd(validUserPasswordQo.getUserPassword());

            if (frameUserPassword.getPassword().equalsIgnoreCase(pwd)){
                if ((StringUtils.isNotBlank(frameUserPassword.getForgetPwdLock()) && frameUserPassword.getForgetPwdLock().equals("1")) ||
                        frameUserPassword.getForgetPwdLockTime()!=null){
                    Map<String, Object> param = Maps.newHashMap();
                    param.put("forgetPwdLock", "0");
                    param.put("forgetPwdLockTime",null);
                    param.put("updateBy", "system");
                    param.put("updateDate", new Date());
                    param.put("id", frameUserPassword.getId());
                    zpzOauthFrameUserPasswordMapper.updateForgetPwdLockByIdList(param);
                }

                ret.setValidStatus(0);
                ret.setValidSurplusCount(UserPasswordMaxErrorCount);
                boolean retDel= zpzOauthRedisService.delete(redisKey);
                if (retDel){
                    log.info("删除缓存成功："+redisKey);
                }else {
                    log.info("删除缓存失败："+redisKey);
                }
                return ZpzOauthResultMsg.okForData(ret);
            }else{
                errorCount++;
                ret.setValidStatus(1);
                if (errorCount==UserPasswordMaxErrorCount){
                    ret.setValidStatus(1);
                    ret.setValidSurplusCount(0);

                    Map<String, Object> param = Maps.newHashMap();
                    param.put("forgetPwdLock", "1");
                    param.put("forgetPwdLockTime",new Date());
                    param.put("updateBy", "system");
                    param.put("updateDate", new Date());
                    param.put("id", frameUserPassword.getId());
                    zpzOauthFrameUserPasswordMapper.updateForgetPwdLockByIdList(param);
                    zpzOauthRedisService.delete(redisKey);
                    return ZpzOauthResultMsg.okForData(ret);
                }else{
                    ret.setValidSurplusCount(UserPasswordMaxErrorCount-errorCount);
                    // 密码错误 存入redis
                    long expireTime = zpzOauthRedisService.getExpire(redisKey);
                    if (expireTime > 0) {
                        zpzOauthRedisService.incr(redisKey, expireTime);
                    }else {
                        zpzOauthRedisService.incr(redisKey, LockAccountSeconds);
                    }
                }
            }
            return ZpzOauthResultMsg.okForData(ret);
        }else{
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_INFO_BY_USER_NAME_30001);
        }
    }


    /**
     * 修改用户与数据权限组关系
     * @param usercode
     * @param groupcode
     * @param ucodeLicense
     * @return
     */
    public void changeUserFrameDataAccess(String usercode,String groupcode,String remarks,String ucodeLicense){
        if (!StringUtils.isBlank(groupcode)) {
            List<String> groupcodelist = getList(groupcode);
            //删除
            Map mapParam = new HashMap();
            mapParam.put("userCode",usercode);
            mapParam.put("updateBy", ucodeLicense);
            mapParam.put("updateDate", new Date());
            dataOauthFrameUserGroupMapper.deleteFrameUserDataGroup(mapParam);
            //新增
            for (String item:groupcodelist) {
                FrameUserDataGroup obj =new FrameUserDataGroup();
                obj.setUserCode(usercode);
                obj.setGroupCode(item);
                obj.setRemarks(remarks);
                obj.setCreateBy(ucodeLicense);
                obj.setCreateDate(new Date());
                obj.setUpdateBy(ucodeLicense);
                obj.setUpdateDate(new Date());
                obj.setDelFlag(0);
                dataOauthFrameUserGroupMapper.addFrameUserDataGroup(obj);
            }
        }
    }

    /**
     * 字符串转数组
     * @param id
     * @return
     */
    private List<String> getList(String id) {
        List<String> list = new ArrayList<String>();
        String[] str = id.split(",");
        for (int i = 0; i < str.length; i++) {
            list.add(str[i]);
        }
        return list;
    }
    /**
     *
     * 功能描述: 修改手机号码
     *
     * @param modifyPhoneNumberQo
     * @return
     * @author: lin
     * @date: 2019/5/31 15:39
     */
    @Override
    public ZpzOauthResultMsg<Boolean> modifyPhoneNumber(HttpServletRequest request,ModifyPhoneNumberQo modifyPhoneNumberQo){
        Map<String, String> license = ZpzOauthRequestUtil.getLicense(request);
        if (license==null || license.size()==0){
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10023);
        }
        String ucodeLicense=license.get("ucode");
        if (StringUtils.isBlank(ucodeLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10027);
        }

        //验证验证码是否正确
        ValidationSmsQo validationSmsQo = new ValidationSmsQo();
        validationSmsQo.setPhone(modifyPhoneNumberQo.getPhoneNumber());
        validationSmsQo.setValidateContent(modifyPhoneNumberQo.getValidCode());
        //验证验证码是否正确
        boolean b = ZpzOauthMsgUtils.validateMsgCode(validationSmsQo.getPhone(), validationSmsQo.getValidateContent());
        if (!b) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_VALID_CODE_ERROR_30005);
        }

        // 校验用户是否存在
        FrameUser up = new FrameUser();
        up.setPhoneNumber(modifyPhoneNumberQo.getPhoneNumber());
        up.setUserCode(ucodeLicense);
        up.setDelFlag(0);
        List<FrameUser> ups = zpzOauthFrameUserMapper.select(up);
        if (ups != null && ups.size() > 0) {
            //该手机号已经存在，无法更新
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_MOBILE_EXIST_ERROR_30008, true);
        } else {
            FrameUser obj=new FrameUser();
            obj.setUserCode(ucodeLicense);
            obj.setPhoneNumber(modifyPhoneNumberQo.getPhoneNumber());
            obj.setUpdateBy(ucodeLicense);
            obj.setUpdateDate(new Date());
            Integer ret= zpzOauthFrameUserMapper.updateUserInfo(obj);
            if (ret>0){
                return ZpzOauthResultMsg.okForData(true);
            }else {
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_PHONE_FAILURE_31006);
            }
        }
    }

    /**
     * 验证是否首次登录
     * */
    @Override
    public ZpzOauthResultMsg<Boolean> checkIsFirstLogin(Map<String,String> license){
        String clientIdLicense = license.get("clientId");
        if (StringUtils.isBlank(clientIdLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10026);
        }
        String ucodeLicense=license.get("ucode");
        if (StringUtils.isBlank(ucodeLicense)) {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10027);
        }

        FrameUserPassword fup = new FrameUserPassword();
        fup.setUserCode(ucodeLicense);
        fup.setClientId(clientIdLicense);
        List<FrameUserPassword> fus = zpzOauthFrameUserPasswordMapper.select(fup);
        if (fus != null && fus.size() > 0) {
            FrameUserPassword frameUserPassword=fus.get(0);
            //不等于1为首次登录
            if (!frameUserPassword.getDefaultFlag().equals(1)){
                return ZpzOauthResultMsg.okForData(true);
            }else{
                return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_ISFIRST_LOGIN_31055);
            }
        } else {
            return ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.USER_INFO_BY_USER_NAME_30001);
        }
    }


    @Override
    public ZpzOauthResultMsg<Boolean> validImgCode(HttpServletResponse response,HttpServletRequest request, ValidImgCodeQo validImgCodeQo) {
        ZpzOauthResultMsg<Boolean> error=ZpzOauthResultMsg.error();
        // 验证图形验证码
        Cookie uuidCookie = CookieUtil.getCookieByName(request, "i_v_c_k");
        if (uuidCookie == null) {
            error.setMessage("无效的图像验证码");
            return error;
        }
        String uuid = uuidCookie.getValue();
        String verifyCode = zpzOauthRedisService.get(uuid);
        if (!validImgCodeQo.getImgCode().equals(verifyCode)) {
            error.setMessage("图像验证码输入错误");
            return error;
        } else {
            zpzOauthRedisService.delete(uuid);
            CookieUtil.removeCookie(response,"i_v_c_k");
            return ZpzOauthResultMsg.okForData(true);
        }
    }
    @Override
    public ZpzOauthResultMsg<String> validMobileMsgAndImgCode(HttpServletResponse response,HttpServletRequest request, ValidMobileMsgAndImgCodeQo validMobileMsgAndImgCodeQo) {
        ZpzOauthResultMsg<String> error=ZpzOauthResultMsg.error();
        //验证短信验证码
        ZpzOauthResultMsg<Boolean> b = ZpzOauthMsgUtils.validateMsgCodeRe(validMobileMsgAndImgCodeQo.getMobile(),validMobileMsgAndImgCodeQo.getShortMsgCode());
        if (b==null||b.getCode()!=0||!b.getData()){
            error.setMessage(b.getMessage());
            return error;
        }
        // 验证图形验证码
        Cookie uuidCookie = CookieUtil.getCookieByName(request, "i_v_c_k");
        if (uuidCookie == null) {
            error.setMessage("无效的图像验证码");
            return error;
        }
        String uuid = uuidCookie.getValue();
        String verifyCode = zpzOauthRedisService.get(uuid);
        if (!validMobileMsgAndImgCodeQo.getImgCode().equals(verifyCode)) {
            error.setMessage("图像验证码输入错误");
            return error;
        } else {
            // 验证手机号
            ZpzOauthResultMsg<UserAuthenticationVo> re =
                    zpzOauthFrameUserService.findUserByPhoneNumberCodeLogin(validMobileMsgAndImgCodeQo.getMobile(), validMobileMsgAndImgCodeQo.getClientId(),validMobileMsgAndImgCodeQo.getClientId());
            if (re != null&&re.getData()!=null&&re.getCode()==0) {
                zpzOauthRedisService.delete(uuid);
                String  uid=UUID.randomUUID().toString();
                // 验证状态保持五分钟
                CookieUtil.addCookie(response,"f_g_p_k",ZpzOauthMd5SaltUtil.getPwd(uid),300);
                return ZpzOauthResultMsg.okForData(uid);
            } else {
                error.setMessage("无效的用户");
                return error;
            }
        }
    }
    @Override
    public ZpzOauthResultMsg<Boolean> modifyPwdByMobileMsgAndImgCode(HttpServletResponse response,HttpServletRequest request,ModifyPwdByMobileMsgAndImgCodeQo modifyPwdByMobileMsgAndImgCodeQo) {
        ZpzOauthResultMsg<Boolean> error=ZpzOauthResultMsg.error();
        ValidMobileMsgAndImgCodeQo vm=new ValidMobileMsgAndImgCodeQo();
        BeanUtils.copyProperties(modifyPwdByMobileMsgAndImgCodeQo,vm);
        Cookie uid = CookieUtil.getCookieByName(request, "f_g_p_k");
        if (uid==null||!StringUtils.isNotBlank(uid.getValue())){
            error.setMessage("手机号验证码和图形验证码校验失败");
            return error;
        }
        if (!ZpzOauthMd5SaltUtil.getPwd(modifyPwdByMobileMsgAndImgCodeQo.getValidCode()).equals(uid.getValue())){
            error.setMessage("手机号验证码和图形验证码校验失败");
            return error;
        }
        ForgetPwdQo fp=new ForgetPwdQo();
        fp.setPassword(modifyPwdByMobileMsgAndImgCodeQo.getNewPwd());
        fp.setPhoneNumber(modifyPwdByMobileMsgAndImgCodeQo.getMobile());
        return forgetPwd(modifyPwdByMobileMsgAndImgCodeQo.getClientId(), fp);
    }

    @Override
    public ZpzOauthResultMsg<Boolean> modifyPwdByMobile(ModifyPwdByMobileQo modifyPwdByMobileQo) {
        ZpzOauthResultMsg<Boolean> error=ZpzOauthResultMsg.error();
        //验证验证码
        boolean b = ZpzOauthMsgUtils.validateMsgCode(modifyPwdByMobileQo.getMobile(),modifyPwdByMobileQo.getShortMsgCode());
        if (!b){
            error.setMessage("短信验证码错误或者过期");
            return error;
        }
        FrameUser fu=new FrameUser();
        fu.setPhoneNumber(modifyPwdByMobileQo.getMobile());
        List<FrameUser> list = zpzOauthFrameUserMapper.select(fu);
        FrameUserPassword fup=new FrameUserPassword();
        fup.setDeleteStatus(0);
        fup.setUserCode(list.get(0).getUserCode());
        fup.setClientId(modifyPwdByMobileQo.getClientId());
        List<FrameUserPassword> fups = zpzOauthFrameUserPasswordMapper.select(fup);
        String password = ZpzOauthSaltUtil.getPwd(modifyPwdByMobileQo.getOldPwd());
        if (!password.equals(fups.get(0).getPassword())){
            error.setMessage("旧密码错误");
            return error;
        }
        ForgetPwdQo fp=new ForgetPwdQo();
        fp.setPassword(modifyPwdByMobileQo.getNewPwd());
        fp.setPhoneNumber(modifyPwdByMobileQo.getMobile());
        return forgetPwd(modifyPwdByMobileQo.getClientId(), fp);
    }

    @Override
    public ZpzOauthResultMsg<Boolean> modifyMobile(ModifyMobileQo modifyMobileQo) {
        ZpzOauthResultMsg<Boolean> error=ZpzOauthResultMsg.error();
        //验证验证码
        boolean b = ZpzOauthMsgUtils.validateMsgCode(modifyMobileQo.getNewMobile(),modifyMobileQo.getShortMsgCode());
        if (!b){
            error.setMessage("短信验证码错误或者过期");
            return error;
        }
        FrameUser fu = new FrameUser();
        fu.setPhoneNumber(modifyMobileQo.getOldMobile());
        fu.setDelFlag(0);
        List<FrameUser> fus = zpzOauthFrameUserMapper.select(fu);
        if (fus != null && fus.size() > 0) {
            FrameUser fu1 = new FrameUser();
            fu1.setPhoneNumber(modifyMobileQo.getNewMobile());
            fu1.setDelFlag(0);
            List<FrameUser> fus1 = zpzOauthFrameUserMapper.select(fu1);
            if (fus1!=null&&fus1.size()>0){
                error.setMessage("新手机号已经存在");
                return error;
            }
            FrameUser frameUser = fus.get(0);
            FrameUser uu = new FrameUser();
            uu.setUserCode(frameUser.getUserCode());
            uu.setPhoneNumber(modifyMobileQo.getNewMobile());
            zpzOauthFrameUserMapper.updateUserInfo(uu);
            return ZpzOauthResultMsg.okForData(true);
        } else {
            error.setMessage("无效的旧手机号");
            return error;
        }
    }

    @Override
    public ZpzOauthResultMsg<Boolean> sendMsgCode(SendMsgCodeQo sendMsgCodeQo) {
        return ZpzOauthMsgUtils.sendMsgCode(sendMsgCodeQo.getPhone());
    }
}
